package com.fingard.dsp.bank.directbank.gzdsf01.util;

import com.fingard.FGBiz;

import javax.crypto.Cipher;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESedeKeySpec;
import java.io.*;
import java.security.Key;
import java.security.MessageDigest;
import java.text.DecimalFormat;
import java.util.StringTokenizer;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class CfbsAPI {
    @SuppressWarnings("unused")
    private static final String CFBS_RETCD_SUC = "000";
    @SuppressWarnings("unused")
    private static final String CFBS_RETCD_FAL = "102";
    @SuppressWarnings("unused")
    private static final int CFBS_ACTCD_ENC = 0;
    @SuppressWarnings("unused")
    private static final int CFBS_ACTCD_DEC = 1;
    @SuppressWarnings("unused")
    private static final String CFBS_PUB_KEY = "19F5E38C";
    @SuppressWarnings("unused")
    private static final int CFBS_MSG_MAX_LEN = 9999;
    @SuppressWarnings("unused")
    private static final int CFBS_MAC_LEN = 64;
    @SuppressWarnings("unused")
    private static final int CFBS_PREFIX_MAC_LEN = 10;
    @SuppressWarnings("unused")
    private static final int CFBS_PREFIX_TXN_LEN = 128;
    @SuppressWarnings("unused")
    private static final int CFBS_KEY_LEN = 24;
    @SuppressWarnings("unused")
    private static final long CFBS_MAX_FILE_SIZE = 99999999L;
    @SuppressWarnings("unused")
    private static final int CFBS_BUF_SIZE = 1024;
    private boolean blnDebug;
    private String strMsg;
    private long lngLength;
    private String strMac;
    private String strRetcd;
    private String strKey;
    private int intAction;
    private String strInMsg;
    private long lngInLength;
    private String strOutMsg;
    private long lngOutLength;
    private String strInFilename;
    private String strOutFilename;

    public CfbsAPI() {
        this.blnDebug = false;
    }

    public CfbsAPI(boolean blnDebug) {
        this.blnDebug = blnDebug;
    }

    public int getIntAction() {
        return this.intAction;
    }

    public void setIntAction(int intAction) {
        this.intAction = intAction;
    }

    public long getLngLength() {
        return this.lngLength;
    }

    public void setLngLength(long lngLength) {
        this.lngLength = lngLength;
    }

    public String getStrInFilename() {
        return this.strInFilename;
    }

    public void setStrInFilename(String strInFilename) {
        this.strInFilename = strInFilename;
    }

    public String getStrKey() {
        return this.strKey;
    }

    public void setStrKey(String strKey) {
        this.strKey = strKey;
    }

    public String getStrMac() {
        return this.strMac;
    }

    public void setStrMac(String strMac) {
        this.strMac = strMac;
    }

    public String getStrMsg() {
        return this.strMsg;
    }

    public void setStrMsg(String strMsg) {
        this.strMsg = strMsg;
    }

    public String getStrOutFilename() {
        return this.strOutFilename;
    }

    public void setStrOutFilename(String strOutFilename) {
        this.strOutFilename = strOutFilename;
    }

    public String getStrRetcd() {
        return this.strRetcd;
    }

    public void setStrRetcd(String strRetcd) {
        this.strRetcd = strRetcd;
    }

    public long getLngInLength() {
        return this.lngInLength;
    }

    public void setLngInLength(long lngInLength) {
        this.lngInLength = lngInLength;
    }

    public long getLngOutLength() {
        return this.lngOutLength;
    }

    public void setLngOutLength(long lngOutLength) {
        this.lngOutLength = lngOutLength;
    }

    public String getStrInMsg() {
        return this.strInMsg;
    }

    public void setStrInMsg(String strInMsg) {
        this.strInMsg = strInMsg;
    }

    public String getStrOutMsg() {
        return this.strOutMsg;
    }

    public void setStrOutMsg(String strOutMsg) {
        this.strOutMsg = strOutMsg;
    }

    private String strReplace(String from, String to, String source) {
        StringBuffer bf = new StringBuffer("");
        StringTokenizer st = new StringTokenizer(source, from, true);
        while (st.hasMoreTokens()) {
            String tmp = st.nextToken();
            if (tmp.equals(from)) {
                bf.append(to);
            } else {
                bf.append(tmp);
            }
        }
        return bf.toString();
    }

    private String byte2hex(byte[] b) {
        char[] cHex = new char[b.length * 2];
        for (int i = 0; i < b.length; i++) {
            cHex[(2 * i)] = "0123456789ABCDEF".charAt(0xF & b[i] >> 4);
            cHex[(2 * i + 1)] = "0123456789ABCDEF".charAt(b[i] & 0xF);
        }
        return new String(cHex);
    }

    private byte[] hex2byte(String strHex) throws Exception {
        try {
            if (strHex.length() % 2 != 0) {
                return null;
            }
            byte[] bts = new byte[strHex.length() / 2];
            for (int i = 0; i < bts.length; i++) {
                bts[i] = ((byte) Integer.parseInt(strHex.substring(i * 2, i * 2 + 2), 16));
            }
            return bts;
        } catch (Exception e) {
            throw (e);
        }
        //return null;
    }

    public static String rightFill(String sourceStr, int strLength, String fillChar) throws Exception {
        int length = 0;
        try {
            if (null != sourceStr) {
                length = sourceStr.getBytes("GBK").length;
            }

            for (int i = 0; i < strLength - length; i++) {
                if (sourceStr == null)
                    sourceStr = fillChar;
                else
                    sourceStr = sourceStr + fillChar;
            }
        } catch (Exception e) {
            throw (e);
        }
        return sourceStr;
    }

    private byte[] DESEncrypt(byte[] bData, String strHexKey, boolean blnFlag) throws Exception {
        try {
            DESedeKeySpec dks = new DESedeKeySpec(hex2byte(strHexKey));
            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DESede");
            Key key = keyFactory.generateSecret(dks);
            Cipher cipher = Cipher.getInstance("DESede");
            if (blnFlag) {
                cipher.init(1, key);
            } else {
                cipher.init(2, key);
            }
            return cipher.doFinal(bData);
        } catch (Exception e) {
            throw (e);
        }
        //return null;
    }

    public void ORG_MAC() throws Exception {
        byte[] byeContent = (byte[]) null;
        String strHexKey = null;
        byte[] byeHexKey = (byte[]) null;
        if (this.blnDebug) {
//			System.out.println("INFO: ORG_MAC...");
        }
        if (this.lngLength <= 98L) {
//			System.out.println("ERROR: lngLength = [" + String.valueOf(this.lngLength) + "] invalid!");
            FGBiz.limitMsg.error("CfbsAPI.ORG_MAC", "ERROR: lngLength = [" + String.valueOf(this.lngLength) + "] invalid!");
            this.strRetcd = "102";
            return;
        }
        //if (this.blnDebug) {
//			System.out.println("INFO: input string = [" + String.valueOf(this.lngLength) + "][" + this.strMsg + "]");
        //}
        try {
            if (this.lngLength > 9999L) {
                byeContent = this.strMsg.getBytes("GBK");
                byeContent = new String(byeContent, 0, 9935, "GBK").getBytes("GBK");
            } else {
                byeContent = this.strMsg.getBytes("GBK");
                byeContent = new String(byeContent, 0, (int) this.lngLength - 64, "GBK").getBytes("GBK");
            }
            strHexKey = strReplace(" ", "0", this.strMsg.substring(10, 34));

            byeHexKey = byte2hex(strHexKey.getBytes("GBK")).getBytes("GBK");

            MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
            messageDigest.update(byeHexKey);
            messageDigest.update(byeContent);

            this.strMac = byte2hex(messageDigest.digest());
            //if (this.blnDebug) {
//				System.out.println("INFO: gen mac cont = [" + byeContent.length + "][" + new String(byeContent, "GBK") + "]");
//				System.out.println("INFO: MAC: [" + this.strMac + "]");
            //}
        } catch (Exception e) {
            throw (e);
            //this.strRetcd = "102";
            //return;
        }
        this.strRetcd = "000";
    }

    public void ORG_TXN_CRYPT() throws Exception {
        String strHexKey = null;
        String strPubKey = null;
        byte[] byeHexKey = (byte[]) null;
        byte[] byePubKey = (byte[]) null;
        byte[] byeData = (byte[]) null;
        byte[] byeData128 = (byte[]) null;
        byte[] byeDataTmp = (byte[]) null;

        int intLoop = 0;
        int intFixLen = 0;
//		if (this.blnDebug) {
//			System.out.println("INFO: ORG_TXN_CRYPT()...");
//			System.out.println("INFO: ORG_TXN_CRYPT()");
//		}
        if ((this.intAction != 0) && (this.intAction != 1)) {
            //System.out.println("ERROR: unknown action [" + String.valueOf(this.intAction) + "]!");
            FGBiz.limitMsg.error("CfbsAPI.ORG_TXN_CRYPT", "ERROR: unknown action [" + String.valueOf(this.intAction) + "]!");
            this.strRetcd = "102";
            return;
        }
        if (this.lngInLength <= 0L) {
            //System.out.println("ERROR: lngInLength = [" + String.valueOf(this.lngInLength) + "] invalid!");
            FGBiz.limitMsg.error("CfbsAPI.ORG_TXN_CRYPT", "ERROR: lngInLength = [" + String.valueOf(this.lngInLength) + "] invalid!");
            this.strRetcd = "102";
            return;
        }
        strHexKey = this.strKey.trim();
        if ((strHexKey.length() == 0) || (strHexKey.length() > 24)) {
            //System.out.println("ERROR: key [" + strHexKey + "] is invalid!");
            FGBiz.limitMsg.error("CfbsAPI.ORG_TXN_CRYPT", "ERROR: key [" + strHexKey + "] is invalid!");
            this.strRetcd = "102";
            return;
        }
//		if (this.blnDebug) {
//			System.out.println("INFO: input key = [" + this.strKey + "]");
//			System.out.println("INFO: input action = [" + this.intAction + "]");
//			System.out.println("INFO: input string = [" + this.lngInLength + "] [" + this.strInMsg + "]");
//		}
        try {
            intFixLen = 24 - strHexKey.length();
            for (intLoop = 0; intLoop < intFixLen; intLoop++) {
                strHexKey = strHexKey + "0";
            }
            byeHexKey = byte2hex(strHexKey.getBytes("GBK")).getBytes("GBK");
            strHexKey = new String(byeHexKey);

            strPubKey = "19F5E38C";
            intFixLen = 24 - strPubKey.length();
            for (intLoop = 0; intLoop < intFixLen; intLoop++) {
                strPubKey = strPubKey + "0";
            }
            byePubKey = byte2hex(strPubKey.getBytes("GBK")).getBytes("GBK");
            strPubKey = new String(byePubKey, "GBK");
            if (this.intAction == 0) {
                byeData = DESEncrypt(this.strInMsg.getBytes("GBK"), strHexKey, true);
                if (byeData == null) {
                    //System.out.println("ERROR: encrypt real-time message failed 1!");
                    FGBiz.limitMsg.error("CfbsAPI.ORG_TXN_CRYPT", "ERROR: encrypt real-time message failed 1!");
                    this.strRetcd = "102";
                    return;
                }
                byeDataTmp = byte2hex(byeData).getBytes("GBK");
                if (byeDataTmp.length <= 128) {
                    byeData128 = DESEncrypt(byeDataTmp, strPubKey, true);
                    if (byeData128 == null) {
                        //System.out.println("ERROR: encrypt real-time message failed 2!");
                        FGBiz.limitMsg.error("CfbsAPI.ORG_TXN_CRYPT", "ERROR: encrypt real-time message failed 2!");
                        this.strRetcd = "102";
                        return;
                    }
                    DecimalFormat df = new DecimalFormat("0000");
                    this.strOutMsg = (df.format(byte2hex(byeData128).length()) + byte2hex(byeData128));
                    this.lngOutLength = this.strOutMsg.length();
                } else {
                    byeData128 = DESEncrypt(byte2hex(byeData).substring(0, 128).getBytes("GBK"), strPubKey, true);
                    if (byeData128 == null) {
                        //System.out.println("ERROR: encrypt real-time message failed 3!");
                        FGBiz.limitMsg.error("CfbsAPI.ORG_TXN_CRYPT", "ERROR: encrypt real-time message failed 3!");
                        this.strRetcd = "102";
                        return;
                    }
                    String strTmp = byte2hex(byeData128) + byte2hex(byeData).substring(128);

                    DecimalFormat df = new DecimalFormat("0000");
                    this.strOutMsg = (df.format(byte2hex(byeData128).length()) + strTmp);
                    this.lngOutLength = this.strOutMsg.length();
                }
            } else {
                String strTmp = null;
                int intPrefixLen = Integer.parseInt(this.strInMsg.substring(0, 4));
                if (intPrefixLen == this.strInMsg.getBytes("GBK").length - 4) {
                    byeData128 = DESEncrypt(hex2byte(this.strInMsg.substring(4)), strPubKey, false);
                    if (byeData128 == null) {
                        //System.out.println("ERROR: decrypt real-time message failed 1!");
                        FGBiz.limitMsg.error("CfbsAPI.ORG_TXN_CRYPT", "ERROR: decrypt real-time message failed 1!");
                        this.strRetcd = "102";
                        return;
                    }
                    strTmp = new String(byeData128, "GBK");
                } else {
                    byeData128 = DESEncrypt(hex2byte(this.strInMsg.substring(4, intPrefixLen + 4)), strPubKey, false);
                    if (byeData128 == null) {
                        //System.out.println("ERROR: decrypt real-time message failed 2!");
                        FGBiz.limitMsg.error("CfbsAPI.ORG_TXN_CRYPT", "ERROR: decrypt real-time message failed 2!");
                        this.strRetcd = "102";
                        return;
                    }
                    strTmp = new String(byeData128, "GBK") + this.strInMsg.substring(intPrefixLen + 4);
                }
                byeData = DESEncrypt(hex2byte(strTmp), strHexKey, false);
                if (byeData == null) {
                    //System.out.println("ERROR: decrypt real-time message failed 3!");
                    FGBiz.limitMsg.error("CfbsAPI.ORG_TXN_CRYPT", "ERROR: decrypt real-time message failed 3!");
                    this.strRetcd = "102";
                    return;
                }
                this.strOutMsg = new String(byeData, "GBK");
                this.lngOutLength = byeData.length;
            }
        } catch (Exception e) {
            throw (e);
            //this.strRetcd = "102";
            //return;
        }
        //if (this.blnDebug) {
        //	System.out.println("INFO: crypt succeeded [" + this.lngOutLength + "] [" + this.strOutMsg + "]");
        //}
        this.strRetcd = "000";
    }

    public void ORG_FILE_CRYPT() throws Exception {
        String strLocKey = null;

        File fInFile = null;
        //if (this.blnDebug) {
        //	System.out.println("INFO: ORG_FILE_CRYPT()");
        //}
        if ((this.intAction != 0) && (this.intAction != 1)) {
            //System.out.println("ERROR: unknown action [" + String.valueOf(this.intAction) + "]!");
            FGBiz.limitMsg.error("CfbsAPI.ORG_FILE_CRYPT", "ERROR: unknown action [" + String.valueOf(this.intAction) + "]!");
            this.strRetcd = "102";
            return;
        }
        strLocKey = this.strKey.trim();
        if ((strLocKey.length() == 0) || (strLocKey.length() > 24)) {
            //System.out.println("ERROR: key [" + strLocKey + "] is invalid!");
            FGBiz.limitMsg.error("CfbsAPI.ORG_FILE_CRYPT", "ERROR: key [" + strLocKey + "] is invalid!");
            this.strRetcd = "102";
            return;
        }
        fInFile = new File(this.strInFilename);
        if (!fInFile.exists()) {
            //System.out.println("ERROR: file [" + this.strInFilename + "] not exist!");
            FGBiz.limitMsg.error("CfbsAPI.ORG_FILE_CRYPT", "ERROR: file [" + this.strInFilename + "] not exist!");
            this.strRetcd = "102";
            return;
        }
        if (fInFile.length() == 0L) {
            //System.out.println("ERROR: file [" + this.strInFilename + "] is empty!");
            FGBiz.limitMsg.error("CfbsAPI.ORG_FILE_CRYPT", "ERROR: file [" + this.strInFilename + "] is empty!");
            this.strRetcd = "102";
            return;
        }
        //if (this.blnDebug) {
        //	System.out.println("INFO: input key = [" + this.strKey + "]");
        //	System.out.println("INFO: input action = [" + this.intAction + "]");
        //	System.out.println("INFO: input file = [" + this.strInFilename + "]");
        //}
        if (this.intAction == 0) {
            fileEncrypt();
        } else {
            fileDecrypt();
        }
        //if ((this.blnDebug) && (this.strRetcd == "000")) {
        //	System.out.println("INFO: ouput file = [" + this.strOutFilename + "]");
        //}
    }

    private void fileEncrypt() throws Exception {
        String strHexKey = null;
        String strPubKey = null;
        byte[] byeHexKey = (byte[]) null;
        byte[] byePubKey = (byte[]) null;
        String strTmpFileName = null;
        String strZipFileName = null;
        String strOutFileName = null;
        String strFileName = null;
        String strFilePath = null;
        String strLine = null;
        String strData = null;
        byte[] byeData = (byte[]) null;
        byte[] byeData128 = (byte[]) null;
        byte[] byeLineEnd = new byte[2];
        byeLineEnd[0] = 13;
        byeLineEnd[1] = 10;

        int intIndex = 0;
        int intLoop = 0;
        int intFixLen = 0;

        File fTmpFile = null;
        File fZipFile = null;
        File fOutFile = null;
        try {
            strHexKey = this.strKey.trim();
            intFixLen = 24 - strHexKey.length();
            for (intLoop = 0; intLoop < intFixLen; intLoop++) {
                strHexKey = strHexKey + "0";
            }
            byeHexKey = byte2hex(strHexKey.getBytes("GBK")).getBytes("GBK");
            strHexKey = new String(byeHexKey);

            strPubKey = "19F5E38C";
            intFixLen = 24 - strPubKey.length();
            for (intLoop = 0; intLoop < intFixLen; intLoop++) {
                strPubKey = strPubKey + "0";
            }
            byePubKey = byte2hex(strPubKey.getBytes("GBK")).getBytes("GBK");
            strPubKey = new String(byePubKey);

            intIndex = this.strInFilename.lastIndexOf("\\");
            if (intIndex <= 0) {
                intIndex = this.strInFilename.lastIndexOf("/");
                if (intIndex <= 0) {
                    //System.out.println("ERROR: file [" + this.strInFilename + "] not include path!");
                    FGBiz.limitMsg.error("CfbsAPI.fileEncrypt", "ERROR: file [" + this.strInFilename + "] not include path!");
                    this.strRetcd = "102";
                    return;
                }
            }
            strFileName = this.strInFilename.substring(intIndex + 1);
            strFilePath = this.strInFilename.substring(0, intIndex);

            strTmpFileName = strFileName + ".tmp";
            fTmpFile = new File(strFilePath, strTmpFileName);
            if (fTmpFile.exists()) {
                fTmpFile.delete();
            }
            fTmpFile.createNewFile();

            InputStream isInFile = new FileInputStream(this.strInFilename);
            InputStreamReader is = null;
            BufferedReader brInFile = null;
            OutputStream osTmpFile = null;
            try {
                is = new InputStreamReader(isInFile, "GBK");
                brInFile = new BufferedReader(is);
                osTmpFile = new FileOutputStream(fTmpFile.getAbsolutePath());
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (is != null) {
                    is.close();
                }
                if (brInFile != null) {
                    brInFile.close();
                }
                if (osTmpFile != null) {
                    osTmpFile.close();
                }
            }
            strLine = brInFile.readLine();
            while (strLine != null) {
                byeData = DESEncrypt(strLine.getBytes("GBK"), strHexKey, true);
                if (byeData == null) {
                    //System.out.println("ERROR: encrypt file data failed 1!");
                    FGBiz.limitMsg.error("CfbsAPI.fileEncrypt", "ERROR: encrypt file data failed 1!");

                    osTmpFile.close();
                    brInFile.close();
                    isInFile.close();
                    fTmpFile.delete();

                    this.strRetcd = "102";
                    return;
                }
                if (byeData.length <= 128) {
                    byeData128 = DESEncrypt(byeData, strPubKey, true);
                    if (byeData128 == null) {
                        //System.out.println("ERROR: encrypt file data failed 2!");
                        FGBiz.limitMsg.error("CfbsAPI.fileEncrypt", "ERROR: encrypt file data failed 2!");

                        osTmpFile.close();
                        brInFile.close();
                        isInFile.close();
                        fTmpFile.delete();

                        this.strRetcd = "102";
                        return;
                    }
                    DecimalFormat df = new DecimalFormat("0000");
                    strData = df.format(byte2hex(byeData128).length()) + byte2hex(byeData128);
                } else {
                    byeData128 = DESEncrypt(byte2hex(byeData).substring(0, 128).getBytes("GBK"), strPubKey, true);
                    if (byeData128 == null) {
                        //System.out.println("ERROR: encrypt file data failed 3!");
                        FGBiz.limitMsg.error("CfbsAPI.fileEncrypt", "ERROR: encrypt file data failed 3!");
                        osTmpFile.close();
                        brInFile.close();
                        isInFile.close();
                        fTmpFile.delete();

                        this.strRetcd = "102";
                        return;
                    }
                    String strTmp = byte2hex(byeData128) + byte2hex(byeData).substring(128);

                    DecimalFormat df = new DecimalFormat("0000");
                    strData = df.format(byte2hex(byeData128).length()) + strTmp;
                }
                osTmpFile.write(strData.getBytes("GBK"));
                osTmpFile.write(byeLineEnd);

                strLine = brInFile.readLine();
            }
            osTmpFile.close();
            brInFile.close();
            isInFile.close();

            strZipFileName = strTmpFileName + ".gz";
            fZipFile = new File(strFilePath, strZipFileName);
            if (fZipFile.exists()) {
                fZipFile.delete();
            }
            fZipFile.createNewFile();

            FileInputStream fileInputStream = null;
            FileOutputStream fileOutputStream = null;
            GZIPOutputStream gzipOutputStream = null;
            try {
                fileInputStream = new FileInputStream(fTmpFile.getAbsolutePath());
                fileOutputStream = new FileOutputStream(fZipFile.getAbsolutePath());
                gzipOutputStream = new GZIPOutputStream(fileOutputStream);
                byte[] byeBuf = new byte[1024];
                int intNumber;
                while ((intNumber = fileInputStream.read(byeBuf)) != -1) {
                    gzipOutputStream.write(byeBuf, 0, intNumber);
                }
                fTmpFile.delete();
            } catch (Exception e) {
                e.getMessage();
            } finally {
                if (fileInputStream != null) {
                    fileInputStream.close();
                }
                if (fileOutputStream != null) {
                    fileOutputStream.close();
                }
                if (gzipOutputStream != null) {
                    gzipOutputStream.close();
                }
            }

            strOutFileName = strFileName.substring(0, strFileName.length() - 8);
            if (fZipFile.length() > 99999999L) {
                //System.out.println("ERROR: file size [" + String.valueOf(fZipFile.length()) + "] overflow");
                FGBiz.limitMsg.error("CfbsAPI.fileEncrypt", "ERROR: file size [" + String.valueOf(fZipFile.length()) + "] overflow");
                fZipFile.delete();
                this.strRetcd = "102";
                return;
            }
            intFixLen = 8 - String.valueOf(fZipFile.length()).length();
            for (intLoop = 0; intLoop < intFixLen; intLoop++) {
                strOutFileName = strOutFileName + "0";
            }
            strOutFileName = strOutFileName + String.valueOf(fZipFile.length());

            fOutFile = new File(strFilePath, strOutFileName);
            if (fOutFile.exists()) {
                fOutFile.delete();
            }
            fZipFile.renameTo(fOutFile);

            this.strOutFilename = strOutFileName;
            //System.out.println("SUCCESS: strOutFilename [" + strOutFileName + "].");
        } catch (Exception e) {
            throw (e);
            //this.strRetcd = "102";
            //return;
        }
        this.strRetcd = "000";
    }

    @SuppressWarnings("resource")
    private void fileDecrypt() throws Exception {
        String strHexKey = null;
        String strPubKey = null;
        byte[] byeHexKey = (byte[]) null;
        byte[] byePubKey = (byte[]) null;
        String strTmpFileName = null;
        String strZipFileName = null;
        String strOutFileName = null;
        String strFileName = null;
        String strFilePath = null;
        String strLine = null;
        String strData = null;
        byte[] byeData = (byte[]) null;
        byte[] byeData128 = (byte[]) null;
        byte[] byeLineEnd = new byte[2];
        byeLineEnd[0] = 13;
        byeLineEnd[1] = 10;

        int intIndex = 0;
        int intLoop = 0;
        int intFixLen = 0;

        File fTmpFile = null;
        File fZipFile = null;
        File fOutFile = null;
        try {
            strHexKey = this.strKey.trim();
            intFixLen = 24 - strHexKey.length();
            for (intLoop = 0; intLoop < intFixLen; intLoop++) {
                strHexKey = strHexKey + "0";
            }
            byeHexKey = byte2hex(strHexKey.getBytes("GBK")).getBytes("GBK");
            strHexKey = new String(byeHexKey);

            strPubKey = "19F5E38C";
            intFixLen = 24 - strPubKey.length();
            for (intLoop = 0; intLoop < intFixLen; intLoop++) {
                strPubKey = strPubKey + "0";
            }
            byePubKey = byte2hex(strPubKey.getBytes("GBK")).getBytes("GBK");
            strPubKey = new String(byePubKey);

            intIndex = this.strInFilename.lastIndexOf("\\");
            if (intIndex <= 0) {
                intIndex = this.strInFilename.lastIndexOf("/");
                if (intIndex <= 0) {
                    //System.out.println("ERROR: file [" + this.strInFilename + "] not include path!");
                    FGBiz.limitMsg.error("CfbsAPI.fileDecrypt", "ERROR: file [" + this.strInFilename + "] not include path!");
                    this.strRetcd = "102";
                    return;
                }
            }
            strFileName = this.strInFilename.substring(intIndex + 1);
            strFilePath = this.strInFilename.substring(0, intIndex);

            strZipFileName = strFileName + ".ugz";
            fZipFile = new File(strFilePath, strZipFileName);
            if (fZipFile.exists()) {
                fZipFile.delete();
            }
            fZipFile.createNewFile();

            FileInputStream fileInputStream = null;
            GZIPInputStream gzipInputStream = null;
            FileOutputStream fileOutputStream = null;
            try {
                fileInputStream = new FileInputStream(this.strInFilename);
                gzipInputStream = new GZIPInputStream(fileInputStream);
                fileOutputStream = new FileOutputStream(fZipFile.getAbsolutePath());

                byte[] byeBuf = new byte[1024];
                int intNumber;
                while ((intNumber = gzipInputStream.read(byeBuf, 0, byeBuf.length)) != -1) {
                    fileOutputStream.write(byeBuf, 0, intNumber);
                }
            } catch (Exception e) {
                e.getMessage();
            } finally {
                if (fileInputStream != null) {
                    fileInputStream.close();
                }
                if (fileOutputStream != null) {
                    fileOutputStream.close();
                }
                if (gzipInputStream != null) {
                    gzipInputStream.close();
                }
            }
            strTmpFileName = strFileName + ".tmp";
            fTmpFile = new File(strFilePath, strTmpFileName);
            if (fTmpFile.exists()) {
                fTmpFile.delete();
            }
            fTmpFile.createNewFile();

            InputStream isInFile = null;
            InputStreamReader isr = null;
            BufferedReader brInFile = null;
            OutputStream osTmpFile = null;
            try {
                isInFile = new FileInputStream(fZipFile.getAbsolutePath());
                isr = new InputStreamReader(isInFile, "GBK");
                brInFile = new BufferedReader(isr);
                osTmpFile = new FileOutputStream(fTmpFile.getAbsolutePath());
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (isInFile != null) {
                    isInFile.close();
                }
                if (isr != null) {
                    isr.close();
                }
                if (brInFile != null) {
                    brInFile.close();
                }
                if (osTmpFile != null) {
                    osTmpFile.close();
                }
            }
            strLine = brInFile.readLine();
            while (strLine != null) {
                String strTmp = null;
                int intPrefixLen = Integer.parseInt(strLine.substring(0, 4));
                if (intPrefixLen == strLine.getBytes("GBK").length - 4) {
                    byeData128 = DESEncrypt(hex2byte(strLine.substring(4)), strPubKey, false);
                    if (byeData128 == null) {
                        //System.out.println("ERROR: decrypt file data failed 1!");
                        FGBiz.limitMsg.error("CfbsAPI.fileDecrypt", "ERROR: decrypt file data failed 1!");
                        osTmpFile.close();
                        brInFile.close();
                        isInFile.close();
                        fZipFile.delete();
                        fTmpFile.delete();

                        this.strRetcd = "102";
                        return;
                    }
                    strTmp = new String(byeData128, "GBK");
                } else {
                    byeData128 = DESEncrypt(hex2byte(strLine.substring(4, intPrefixLen + 4)), strPubKey, false);
                    if (byeData128 == null) {
                        //System.out.println("ERROR: decrypt file data failed 2!");
                        FGBiz.limitMsg.error("CfbsAPI.fileDecrypt", "ERROR: decrypt file data failed 2!");
                        this.strRetcd = "102";
                        return;
                    }
                    strTmp = new String(byeData128, "GBK") + strLine.substring(intPrefixLen + 4);
                }
                byeData = DESEncrypt(hex2byte(strTmp), strHexKey, false);
                if (byeData == null) {
                    //System.out.println("ERROR: decrypt file data failed!");
                    FGBiz.limitMsg.error("CfbsAPI.fileDecrypt", "ERROR: decrypt file data failed!");
                    osTmpFile.close();
                    brInFile.close();
                    isInFile.close();
                    fZipFile.delete();
                    fTmpFile.delete();

                    this.strRetcd = "102";
                    return;
                }
                strData = new String(byeData, "GBK");
                osTmpFile.write(strData.getBytes("GBK"));
                osTmpFile.write(byeLineEnd);
                strLine = brInFile.readLine();
            }
            osTmpFile.close();
            brInFile.close();
            isInFile.close();

            fZipFile.delete();
            if (fTmpFile.length() > 99999999L) {
                //System.out.println("ERROR: file size [" + String.valueOf(fTmpFile.length()) + "] overflow");
                FGBiz.limitMsg.error("CfbsAPI.fileDecrypt", "ERROR: file size [" + String.valueOf(fTmpFile.length()) + "] overflow");
                fTmpFile.delete();
                this.strRetcd = "102";
                return;
            }
            strOutFileName = strFileName.substring(0, strFileName.length() - 8);

            intFixLen = 8 - String.valueOf(fTmpFile.length()).length();
            for (intLoop = 0; intLoop < intFixLen; intLoop++) {
                strOutFileName = strOutFileName + "0";
            }
            strOutFileName = strOutFileName + String.valueOf(fTmpFile.length());

            fOutFile = new File(strFilePath, strOutFileName);
            if (fOutFile.exists()) {
                fOutFile.delete();
            }
            fTmpFile.renameTo(fOutFile);
            this.strOutFilename = strOutFileName;
            //System.out.println("SUCCESS: strOutFilename [" + strOutFileName + "].");
        } catch (Exception e) {
            throw (e);
            //this.strRetcd = "102";
            //return;
        }
        this.strRetcd = "000";
    }
}
